﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace CxExtension
{
	public static class TypeExt
	{
		private static BindingFlags sBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding;//
		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="self"></param>
		/// <param name="name"></param>
		/// <param name="paramNum">param num not content self</param>
		/// <returns></returns>
		public static T GetMethodFunc<T>(this Type self, string name,int paramNum) where T:class
		{
			return self.GetMethodFunc<T>(name, sBindingFlags, paramNum);

		}
		public static T GetMethodFunc<T>(this Type self, string name, BindingFlags flags, int paramNum) where T:class
		{
			var delegateType = typeof(T);
			var methodInfo = self.GetMethod(name, flags, paramNum);
			var func = Delegate.CreateDelegate(delegateType, methodInfo, true);
			return func as T;

		}

		public static MethodInfo GetMethod(this Type self, string name, int paramNum)
		{
			return self.GetMethod(name, sBindingFlags, paramNum);
		}
		public static MethodInfo GetMethod(this Type self, string name, BindingFlags flags,int paramNum)
		{
			var method = self.GetMethods(name,flags);
			MethodInfo info;
			var has = method.FindA(it =>
			{
				var parameters = it.GetParameters();
				return parameters.Length == paramNum;
			}, out info);
			if (!has)
			{
				var str = method.ToStringAllItem(it => "param:" + it.GetParameters().Length);
				throw new Exception(string.Format("not find:{0} paramNum:{1}\n{2}",name,paramNum,str));
			}
			return info;
		}

		public static List<MethodInfo> GetMethods(this Type self, string name, BindingFlags flags)
		{
			var list = self.GetMethods(name, flags,null);
			return list;
		}
		public static List<MethodInfo> GetMethods(this Type self,string name,BindingFlags flags,List<MethodInfo> list)
		{
			var methods = self.GetMethods(flags);
			var methodInfos = methods.FindAll(it=>it.Name.Contains(name),list);
			if (methodInfos.Count == 0)
			{
				throw new Exception(string.Format("GetMethods not find:{0}", name));
			}
			return methodInfos;
		}

	}
}